QuickTime 3 Reference

| Previous | Chapter contents | Chapter top | Section top | Next |

Using a Movie Data Export Component to Export Video

Using a movie data export component to create a QuickTime movie file is similar in many respects to creating an AIFF file as shown in the previous example. Media data is handled differently in each case, however.

Instantiating the Data Export Component

Listing 11-7 illustrates the first step, instantiating a movie data export component for video data.

Listing 7 Instantiating a movie data export component

ComponentDescription cd;
MovieExportComponent ci;
cd.componentType = MovieExportType;
cd.componentSubType = `MooV';
cd.componentManufacturer = 0;
cd.componentFlags = canMovieExportFromProcedures;
cd.componentFlagsMask = canMovieExportFromProcedures;
ci = OpenComponent(FindNextComponent(nil, &cd));

Configuring the Data Export Component

Listing 11-8 illustrates the next step: configuring the data export component to create a single output video track. The call to MovieExportAddDataSource provides the callback functions for supplying media data.

Listing 8 Configuring the movie data export component

#define kMySampleRate 2997/* 29.97 fps */
#define kMyFrameDuration 100/* one frame at 29.97 fps */
typedef struct
{
    GWorldPtr gw;
    ImageDescriptionHandle imageDescription;
    long trackID;
}
MyReferenceRecord;
MyReferenceRecord myRef;
myRef.gw = nil;
myRef.imageDescription = nil;
MovieExportAddDataSource(ci, VideoMediaType, kMySampleRate,
        &myRef.trackID, getVideoPropertyProc,
        getVideoDataProc, &myRef);

Exporting the Data

At this point, operations could be added. For example, additional video tracks or sound tracks could be created. Once all the output tracks are created, the export operation takes place. This is the same as in the AIFF export example.

Listing 9 Exporting video data

StandardFileReply reply;
Handle dataRef;
// get output file from user
QTNewAlias(&reply.sfFile, (AliasHandle *)&dataRef, true);
MovieExportFromProceduresToDataRef(ci, dataRef, rAliasType);

The getVideoPropertyProc function returns information about the output track's properties (for example, the compression format). If the function doesn't return a value for a particular property, the exporter will choose a default value based (usually) on the source data format. In Listing 11-10 , dimensions are set to 160x120 and the compression format is set to JPEG. All other properties are unspecified.

Listing 10 Obtaining information about output track properties

pascal OSErr getVideoPropertyProc(void *refcon, long trackID, OSType propertyType, void
*propertyValue)
{
    OSErr err = noErr;
    switch (propertyType) {
        case meWidth:
            *(Fixed *)propertyValue = 160L << 16;
            break;
        case meHeight:
            *(Fixed *)propertyValue = 120L << 16;
            break;
        case scSpatialSettingsType:
            {
            SCSpatialSettings *ss = propertyValue;
            ss->codecType = kJPEGCodecType;
            ss->codec = 0;
            ss->depth = 0;
            ss->spatialQuality = codecNormalQuality;
            }
            break;
        default:
            err = paramErr;
            break;
    }
    return err;
}

The videoGetData function provides video frames to the export operation. In the example in Listing 11-11 , the same blank frame is returned for each request. The export operation ends when this function returns eofErr . Any data allocated by videoGetProc must be disposed of after the export operation is complete.

Listing 11 Providing video frames for export

pascal OSErr videoGetData(void *refCon,
        MovieExportGetDataParams *params)
{
    OSErr err = noErr;
    MyReferenceRecord *myRef = (MyReferenceRecord *)refCon;
    TimeRecord tr;
    if (params->requestedTime > kMySampleRate * 10)
        return eofErr;// end of data after 10 seconds
    if (!myRef->gw) {
        Rect r;
        CGrafPtr savePort;
        GDHandle saveGD;
        SetRect(&r, 0, 0, 320, 240);
        NewGWorld(&myRef->gw, 32, &r, nil, nil, 0);
        LockPixels(myRef ->gw->portPixMap);
        MakeImageDescriptionForGWorld(myRef->gw,
                &myRef->imageDescription);
        GetGWorld(&savePort, &saveGD);
        SetGWorld(myRef->gw, nil);
        EraseRect(&r);
        SetGWorld(savePort, saveGD);
    }
    params->dataPtr = GetPixBaseAddr(myRef->gw->portPixMap);
    params->dataSize = (**myRef->imageDescription).dataSize;
    params->actualTime = params->requestedTime;
    params->descType = VideoMediaType;
    params->descSeed = 1;
    params->desc = (SampleDescriptionHandle)
                    myRef->imageDescription;
    params->durationPerSample = kMyFrameDuration;
    params->sampleFlags = 0;
bail:
    return err;
}

© 1997 Apple Computer, Inc.

| Previous | Chapter contents | Chapter top | Section top | Next |